import React, { useRef, useState, useEffect } from 'react'
import { Button, Form, Input, message } from 'antd'
import { DoubleRightOutlined } from '@ant-design/icons'
import { useApi } from '../../api'
import { useNavigate, Navigate } from 'react-router-dom'
import LoginBg from '../../components/LoginBg'
import { useDispatch } from 'react-redux'
import { storeMenu } from '../../store/reducers/tab'
import { aesUtil, rsaUtil, storage } from '../../utils/index'
import { useThrottle } from '../../utils/index'
const { getItem, setItemList } = storage

function Login() {
  //请求接口
  const { register, login, getRsaPublicKey, postAsePublicKey, getCode } = useApi()

  // 登录或者注册
  const [ifLogin, setIfLogin] = useState(true)

  //手机号登录或者密码登陆
  const [ifPhone, setIfPhone] = useState(false)

  //创建form实例
  const [form] = Form.useForm()

  //电话号码
  const [phone, setPhone] = useState('')

  //密钥
  const key = useRef({
    asePublicKey: '',
    rsaPublicKey: ''
  })

  //验证码
  const phoneCode = useRef('')

  const dispatch = useDispatch()

  //是否获取验证码
  const [ifGet, setIfGet] = useState(false)
  //倒计时
  const [time, setTime] = useState(60)
  //定时器
  let timer = null
  useEffect(() => {
    if (time <= 0) {
      clearInterval(timer)
      setIfGet(false)
      setTime(60)
    }
  }, [time])

  //节流+获取手机号
  const handlerGetCode = useThrottle(
    async () => {
      try {
        const p = /^1[3-9]\d{9}$/
        if (phone === '' || !p.test(phone)) {
          message.warning('电话号码格式不对')
          return
        }

        //开始倒计时
        setIfGet(true)
        timer = setInterval(() => {
          setTime(time => time - 1)
        }, 1000)

        // 获取密钥
        await getEncryptKey()

        //获取验证码
        let { encryptCode } = await getCode({
          phone
        })
        let { asePublicKey } = key.current
        // 通过对称加密公钥对验证码进行解密
        const code = aesUtil.decrypt(encryptCode, asePublicKey)
        phoneCode.current = code
        console.log('验证码', code)
      } catch (error) {
        message.error(error)
        console.log('err', error)
      }
    },
    1000,
    true
  )

  //登录或者注册
  const changeLogin = () => {
    setIfLogin(!ifLogin)
  }

  //已登录过，跳转到首页
  const navigate = useNavigate()
  if (getItem('token')) {
    return <Navigate to="/home" replace></Navigate>
  }

  //获取密钥操作
  const getEncryptKey = () => {
    return new Promise(async (resolve, reject) => {
      try {
        //获取非对称加密公钥
        let res = await getRsaPublicKey({
          phone
        })

        const rsaPublicKey = res.rsaPublicKey

        //生成对称加密公钥
        const asePublicKey = aesUtil.genKey()

        //通过非对称加密公钥对（对称加密公钥）加密
        const encryptKey = rsaUtil.encrypt(asePublicKey, rsaPublicKey)

        //将加密的公钥传给服务端
        res = await postAsePublicKey({
          phone,
          encryptKey
        })

        //保存两种公钥
        key.current = {
          ...key,
          asePublicKey,
          rsaPublicKey
        }

        resolve()
      } catch (err) {
        message.error('异常')
        console.log('err', err)
      }
    })
  }

  //密码登陆，手机号加验证码登录
  const handleSubmit = val => {
    if (!val.password || !val.username) {
      return message.open({
        type: 'warning',
        content: '请输入用户名和密码'
      })
    }

    if (ifLogin) {
      login(val).then(
        res => {
          // 保存菜单
          dispatch(storeMenu(res.menu))

          //保存到缓存
          res &&
            setItemList({
              menu: res.menu,
              token: res.token,
              jurisdiction: res.jurisdiction
            })

          message.open({
            type: 'success',
            content: '登录成功',
            duration: 1
          })
          navigate('/home')
        },
        err => {
          message.open({
            type: 'error',
            content: '登录失败',
            duration: 1
          })
        }
      )
    } else {
      register(val).then(
        res => {
          if (res.code == 200) {
            setIfLogin(true)
            form.resetFields()
            message.open({
              type: 'success',
              content: '注册成功',
              duration: 1
            })
          } else {
            message.open({
              type: 'error',
              content: '注册失败',
              duration: 1
            })
          }
        },
        err => {
          message.open({
            type: 'error',
            content: '注册失败',
            duration: 1
          })
        }
      )
    }
  }

  //电话号码登陆
  const handleSubmit1 = () => {
    form.validateFields().then(
      async res => { },
      err => {
        message.error('输入项异常')
      }
    )
  }

  return (
    <div className="w-[100%] h-[100vh] ">
      <LoginBg>
        {/* bg-bg-login pb-[0.1875rem] rounded-[0.1875rem]*/}
        <Form
          style={{ display: ifPhone ? 'none' : 'flex' }}
          className="w-[100%] h-[100%] flex justify-center items-center flex-col border-[0.0125rem] border-solid  bg-no-repeat bg-cover border-[#eaeaea] pt-[0.4375rem] pr-[0.4375rem]  pl-[0.4375rem]  "
          form={form}
          onFinish={handleSubmit}
        >
          {/* 主体内容 */}
          <div className="relative bg-[#eceff7] w-[7.5rem] flex flex-col justify-center items-center p-[0.25rem] rounded-[0.25rem]">
            {/* 登录方式切换 */}
            <Button
              onClick={() => setIfPhone(!ifPhone)}
              className="absolute top-[.25rem] right-[.5rem] bg-transparent border-none text-red-700 font-bold"
            >
              {ifPhone ? '密码' : '手机号'}
            </Button>

            {/* 密码登陆及注册 */}
            <div>
              <div className="text-center mb-[0.5rem] text-[#505458] text-[0.25rem]">
                用户{ifLogin ? '登录' : '注册'}
              </div>
              <Form.Item label="账号" name="username">
                <Input className="w-[2.475rem]" placeholder="请输入账号"></Input>
              </Form.Item>
              <Form.Item label="密码" name="password">
                <Input.Password className="w-[2.475rem]" placeholder="请输入密码"></Input.Password>
              </Form.Item>
              <Form.Item className="flex justify-end w-[3.25rem]">
                <Button className="text-center w-[1rem]" type="primary" htmlType="submit">
                  {ifLogin ? '登录' : '注册'}
                </Button>
                <Button
                  className="text-[0.15rem]  ml-[0.25rem] w-[0.75rem] border-[transparent]"
                  onClick={changeLogin}
                >
                  {ifLogin ? '注册' : '登录'}
                  <DoubleRightOutlined style={{ fontSize: '0.15rem' }} />
                </Button>
              </Form.Item>
            </div>
          </div>
        </Form>

        {/* 手机号登陆 */}
        <Form
          style={{ display: ifPhone ? 'flex' : 'none' }}
          onFinish={handleSubmit1}
          className="w-[100%] h-[100%] flex justify-center items-center flex-col border-[0.0125rem] border-solid  bg-no-repeat bg-cover border-[#eaeaea] pt-[0.4375rem] pr-[0.4375rem]  pl-[0.4375rem]"
        >
          {/* 主体内容 */}
          <div className="relative bg-[#eceff7] w-[7.5rem] flex flex-col justify-center items-center p-[0.25rem] rounded-[0.25rem]">
            {/* 登录方式切换 */}
            <Button
              onClick={() => setIfPhone(!ifPhone)}
              className="absolute top-[.25rem] right-[.5rem] bg-transparent border-none text-red-700 font-bold"
            >
              {ifPhone ? '密码' : '手机号'}
            </Button>
            <div className="text-center mb-[0.5rem] text-[#505458] text-[0.25rem]">
              手机号{ifLogin ? '登录' : '注册'}
            </div>
            <Form.Item
              name="phone"
              rules={[
                { required: true, message: '请输入电话号码' },
                { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的电话号码' }
              ]}
            >
              <Input
                className="w-[3.58rem]"
                placeholder="请输入电话号码"
                value={phone}
                onChange={e => setPhone(e.target.value)}
              ></Input>
            </Form.Item>
            <div className="flex">
              <Form.Item
                name="code"
                rules={[
                  { required: true, message: '请输入验证码' },
                  { len: 4, message: '请输入正确的验证码' }
                ]}
              >
                <Input className="w-[2.475rem]" placeholder="请输入短信验证码"></Input>
              </Form.Item>
              <Form.Item>
                {!ifGet ? (
                  <Button
                    onClick={handlerGetCode}
                    className="w-[1rem] h-[.45rem] text-[.15rem] ml-[.1rem]"
                    type="primary"
                  >
                    短信验证码
                  </Button>
                ) : (
                  <div className="flex justify-center items-center rounded-[.1rem] w-[1rem] h-[.45rem] text-[.2rem] ml-[.1rem] bg-white">
                    {time}
                  </div>
                )}
              </Form.Item>
            </div>
            <Form.Item className="flex justify-center w-[3.25rem]">
              <Button className="text-center w-[1rem]" type="primary" htmlType="submit">
                登录
              </Button>
            </Form.Item>
          </div>
        </Form>
      </LoginBg>
    </div>
  )
}

export default Login
